package com.gusto.engine.repository.dao.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.log4j.Logger;

import com.gusto.engine.beans.exceptions.ResCreationException;
import com.gusto.engine.beans.model.Res;
import com.gusto.engine.beans.model.impl.ObjectModelRes;
import com.gusto.engine.repository.dao.RepositoryDAO;
import com.gusto.engine.repository.exception.RepositoryException;
import com.gusto.engine.repository.params.Param;

/**
 * <p>A database repository relying on JPA to access data.</p>
 * 
 * @author amokrane.belloui@gmail.com
 *
 */
public class DatabaseJpaRepositoryDAO implements RepositoryDAO {
	
	private Logger log = Logger.getLogger(getClass());
	
	private EntityManager entityManager;
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
		log.debug("Setting the entityManager " + entityManager);
	}
	
	/**
	 * 2 parameter are required : [ObjectClass.class], [Value of the object's JPA Id]
	 */
	@SuppressWarnings("unchecked")
	public Res getResource(Object... params) throws ResCreationException, RepositoryException {
		log.info("Loading resource " + params);
		Object obj = entityManager.find((Class)params[0], params[1]);
		return ObjectModelRes.createResource(obj);
	}
	
	/**
	 * Query the database [QueryString] [QueryParams]
	 * @param queryString JPA query (only named parameters)
	 * @param queryParams names Parameters
	 * @return
	 * @throws ResCreationException 
	 */
	@SuppressWarnings("unchecked")
	public List<Res> query(String queryString, Param[] queryParams, Object... params) throws RepositoryException, ResCreationException {
		log.info("Querying database " + queryString);
		Query query = entityManager.createQuery(queryString);
		for (Param p : queryParams) {
			query.setParameter(p.getName(), p.getValue());
		}
		
		List<Res> res = new ArrayList<Res>();
		for (Object o : query.getResultList()) {
			res.add(ObjectModelRes.createResource(o));
		}
		return res;
	}
	
}
